'use strict';

const h = React.createElement;
const GAMENAMES="gameNames";
const GAMEURLS = "gameUrls";
const GAMENOTWORK = "gameNotWork";
const GAMEREDIRECT = "gameRedirect";

let get = (url,callback)=>{
    let xhr = new XMLHttpRequest();
    xhr.addEventListener('error',(e)=>{
        callback&&callback({err:e})
    })
    xhr.addEventListener('load',(e)=>{
        var response = xhr.response;
        callback&&callback({data:response});
    })
    xhr.open('GET',url);
    xhr.send();
}

let startCount = 72,count=24;
let namesArr = [];
/**
 * 检索网站所有游戏名称
 * @param {Function} callback 回调函数
 * @param {Functoin} log  日志函数
 */
let retrieveGameNames = (callback,log)=>{
    let url = `https://51h5.online/api/v1/games/more/undefined/${startCount}-${startCount+count}`;
    console.log("开始搜索游戏名:",url)
    get(url,(res)=>{
        let reg = /game\/([^"]+)"/g
        let arr,key = GAMENAMES;
        let names = [];
        while (arr = reg.exec(res.data)) {  
            console.log('game name:',arr[1])    
            log({
                date:new Date().toTimeString(),
                msg: `游戏名称: ${arr[1]}`
            })      
            names.push(arr[1]);
        }
        namesArr = namesArr.concat(names);
        if(names.length==24){
            startCount+=count;
            retrieveGameNames(callback,log);
        }else{
            console.log('游戏搜索完成',namesArr)
            log({
                date:new Date().toTimeString(),
                msg:'游戏搜索完成，获取到'+namesArr.length+'个游戏'
            })
            localStorage.setItem(key,namesArr); // 直到最后一页写入数据
            callback&&callback(namesArr);
        }
    })
}

/**
 * 通过游戏名称搜索游戏url
 */
let retrieveGameUrls = (callback)=>{
    let gameNames = localStorage.getItem(GAMENAMES).split(',');
    let arr = [],key = GAMEURLS;
    let reqCount = 0,gameUrlsArr = [];
    let retrieveGameUrl = (name)=>{
        const url = `https://51h5.online/play/${name}`;
        get(url,(res)=>{
            reqCount++;
            if(res.err){    //发生错误
                console.log('获取url失败',err)
                return;
            }
            let reg = /\+'([^']+)'\+`"><\/iframe>`/;
            const html = res.data;

            if(arr = html.match(reg)){
                console.log(`发现链接：${name}:${arr[1]}`);
                gameUrlsArr.push({
                    name: name,
                    url: arr[1]
                });
                if(reqCount == gameNames.length){
                    localStorage.setItem(key,JSON.stringify(gameUrlsArr));
                    callback&&callback(gameUrlsArr)
                    console.log('已经存储好gameUrls');
                }
                
            };
        })
    }
    console.log("开始搜索游戏url")
    gameNames.forEach((value)=>{
        retrieveGameUrl(value);
    });
}
let checkUrl = (url,callback)=>{
    let xhr = new XMLHttpRequest();

    xhr.addEventListener('error',e=>{
        callback&&callback({err:e.type})
    });
    xhr.addEventListener('readystatechange',(e)=>{
        let xhr = e.target;
        if(xhr.readyState == xhr.HEADERS_RECEIVED) {
            var code = xhr.getResponseHeader("status");
            console.log(url,code,xhr.status)    
            callback&&callback({data:xhr.status});
            
        }
    })
    xhr.open('GET',url);
    xhr.send();
}
// 检查游戏地址
let checkGameUrls = (callback,log)=>{
    let checkCount = 0,gamesNotWork = [];
    let games = localStorage.getItem(GAMEURLS);
    stopping = false;
    if(games){
        let gamesArr = JSON.parse(games);

        gamesArr.forEach(game=>{
            let url = game.url;
            checkUrl(url,(res)=>{  
                const d = new Date().toTimeString(); 
                if(res.err){
                    console.log('请求出错',res.err);
                    log({
                        date:d,
                        msg:res.err+":"+url
                    })
                    game.code = res.err;
                    gamesNotWork.push(game)
                }else if(res.data!=200){
                    console.log(`header code:${res.data}`)
                    log({
                        date:d,
                        msg:res.data+":"+url
                    })
                    game.code = res.data;
                    gamesNotWork.push(game)
                }
                console.log(`已经检查${checkCount}条，总数${gamesArr.length}`)
                log({
                    date:d,
                    msg:`已经检查${checkCount}条，总数${gamesArr.length}`
                })
                if(++checkCount>gamesArr.length-5){   // 等所有请求执行完一次存入
                    console.log(`执行完毕，有问题的游戏数量为${gamesNotWork.length}`)
                    localStorage.setItem(GAMENOTWORK,JSON.stringify(gamesNotWork));
                    callback&&callback()
                }
            })
        })
    }
}

/**
 * 检查游戏是否自动跳转
 */
let stopping = false;   // 用以标记是否停止所有检查
let checkGameRedirect = (callback,log)=>{
    let gameNames = localStorage.getItem(GAMENAMES).split(',');
    stopping = false;
    let openNewTab = (url,onRemoving)=>{
        chrome.tabs.create({url:url,active:false},tab=>{
            console.log('打开新标签页',tab)
            setTimeout(() => {
                chrome.tabs.remove(tab.id,()=>{
                    console.log('移除tab成功')
                    onRemoving()
                })
            }, 10*1000);
        })
    }
    let tabLoop = index=>{
        callback&&callback(stopping);
        if(index<gameNames.length&&stopping===false){
            const name = gameNames[index];
            const url = `https://51h5.online/play/${name}`;
            openNewTab(url,()=>{
                tabLoop(++index)
            });
        }        
    };


    tabLoop(0);

    chrome.runtime.onMessage.addListener((message,sender)=>{
        const arr = JSON.parse(localStorage.getItem(GAMEREDIRECT))||[];        
        if(Object.keys(message).length){
            console.log('接收到消息',message);
            log({
                date: new Date().toTimeString(),
                msg: `${message.url}+"|页面停留时间：${message.duration}"`
            })
            if(message.duration<5){ // 小于5秒写入跳转游戏
                arr.push(message);
                localStorage.setItem(GAMEREDIRECT,JSON.stringify(arr));
            }

        }
    })

}

class List extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const {gameNotFound,gameUrls,gameRedirect} = this.props
    const list = [];
    var vGameNotFound = gameNotFound.map(item=>{
        return h('li',{},item.url,h('i',{},item.code))
    })
    var vGameRedirect = gameRedirect.map(item=>{
        return h('li',{},item.url,h('i',{},item.duration))
    })
    list.push(h('li',{className:"weui-cell"}, h('label', {},'小游戏数量: '),gameUrls.length))
    list.push(h('li',{className:"weui-cell"}, h('label', {},'URL404数量: '),gameNotFound.length))
    list.push(h('li',{className:"weui-cell"},h('ol',{className:"info-list"},...vGameNotFound)))
    list.push(h('li',{className:"weui-cell"}, h('label', {},'自动跳转数量: '),gameRedirect.length))
    list.push(h('li',{className:"weui-cell"},h('ol',{className:"info-list"},...vGameRedirect)))

    return h(
        'ul',
        {className:"weui-cells"},
        ...list
    );
  }
}

const btnGameUrl = 'gameUrl'
    ,btnGameNotFound = 'gameNotFound'
    ,btnGameRedirect = 'gameRedirect'
    ;
class ButtonGroup extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            loading:false,
            btnType:null,   // 当前点击的button分类
        }
    }  
    
    clickHander(type){
        const _ = this;
        const {onSearchEnd,onLog} = this.props
        const {loading} = this.state
        if(loading) return;
        _.setState({
            loading: true
        })
        switch (type) {
            case btnGameUrl:
                _.setState({
                    btnType: btnGameUrl
                })
                new Promise((resolve,reject)=>{
                    retrieveGameNames((names)=>{
                        resolve(names)
                    },log=>{
                        onLog&&onLog(log)   // 写入日志
                    })
                }).then(data=>{
                    return data;
                },err=>{
                    console.error(err)
                }).then(data=>{
                    retrieveGameUrls(urls=>{
                        onSearchEnd&&onSearchEnd()
                    },log=>{
                        onLog&&onLog(log)   // 写入日志
                    })  
                },err=>{
                    console.error(err)
                }).finally(()=>{
                    _.setState({
                        loading: false,
                        btnType:null
                    })
                })
                break;
            case btnGameNotFound:
                _.setState({
                    btnType: btnGameNotFound
                })

                checkGameUrls((data)=>{
                        onSearchEnd&&onSearchEnd()
                        _.setState({
                            loading: false,
                            btnType:null
                        })
                    },log=>{
                        onLog(log)
                    })
                break;
            default:
                console.log('btnGameRedirect')
                _.setState({
                    btnType: btnGameRedirect
                })   
                checkGameRedirect(()=>{

                },log=>{
                    onLog&&onLog(log)   // 写日志
                })             
                break;
        }
    }

    stopAll(){
        stopping = true;
        this.setState({
            btnType: null,
            loading:false,
        })
    }

    render() {
        const {loading,btnType} = this.state
        const loadingUrl = loading&&btnType===btnGameUrl
            ,loadingNotFound = loading&&btnType===btnGameNotFound
            ,loadingRedirect = loading&&btnType===btnGameRedirect
            ;
        return h('div',{className:"button-sp-area"}
        ,h('button',{ className:"weui-btn weui-btn_mini weui-btn_primary "+(loadingUrl?"weui-btn_loading":""),onClick: () => {this.clickHander(btnGameUrl)} },loadingUrl?h('i',{className:"weui-loading"}):'','获取游戏数量')
        ,h('button', {className:"weui-btn weui-btn_mini weui-btn_primary "+(loadingNotFound?"weui-btn_loading":""),onClick: () => {this.clickHander(btnGameNotFound)} }, loadingNotFound?h('i',{className:"weui-loading"}):'','检查404游戏')
        ,h('button', {className:"weui-btn weui-btn_mini weui-btn_primary "+(loadingRedirect?"weui-btn_loading":""),onClick: () => {this.clickHander(btnGameRedirect)} }, loadingRedirect?h('i',{className:"weui-loading"}):'','检查游戏跳转')
        // ,h('button', {className:"weui-btn weui-btn_mini weui-btn_warn",onClick: () => {this.stopAll()}},'停止检查')
        )
    }
}

class Log extends React.Component{
    constructor(props){
        super(props)
    }

    render(){
        const {list} = this.props;
        const vlist = list.map(item=>{
            return h('li',{},h('i',{},item.date),h('span',{},item.msg));
        })
        return h('div',{className:'log-info'},h('ul',{},...vlist));
    }
}

class Root extends React.Component {
  constructor(props) {
    super(props)    
    this.state = {
        gameUrls: JSON.parse(localStorage.getItem(GAMEURLS))||[],   // 游戏url数组
        gameNotFound:JSON.parse(localStorage.getItem(GAMENOTWORK))||[],   // 游戏url 404数组
        gameRedirect: JSON.parse(localStorage.getItem(GAMEREDIRECT))||[], // 会跳转的游戏链接
        logInfo:[]
    }
  }

  onSearchEnd(){  //搜索结束
    console.log('onSearchEnd')
    this.setState({
        gameUrls: JSON.parse(localStorage.getItem(GAMEURLS))||[],   // 游戏url数组
        gameNotFound:JSON.parse(localStorage.getItem(GAMENOTWORK))||[],   // 游戏url 404数组
    })
  }

  addLog(log){ // 添加日志
    console.log('写入日志')
    const info = this.state.logInfo;
    info.push(log)
    this.setState({
        logInfo: info
    })
  }

  render() {
    const {gameUrls,gameNotFound,gameRedirect} = this.state;
    return h('div', {}, h(List, {gameUrls:gameUrls,gameNotFound:gameNotFound,gameRedirect:gameRedirect}), h(ButtonGroup,{onSearchEnd:()=>{this.onSearchEnd()},onLog:(log)=>{this.addLog(log)}}),h(Log,{list:this.state.logInfo}));
  }
}
/* const item =function (props) {
    return <li><label>{props.title}</label><span>{props.value}</span></li>
}
const data = [{title:'游戏数量',value:1990},{title:'失效数量',value:193}]
const Lists = data.map(value=>{
    item(value)
})*/
const domContainer = document.querySelector('#app');

ReactDOM.render(h(Root), domContainer);
